﻿#include "simulation.h"
#include "lockMng.h"
#include "parse.h"
#include <map>
#include "externInterface.h"
#include "presentation.h"
#include "utils.h"
#include "PageInfoSwitch.h"
#include <exception>
#include "dataCollection.h"
#include <math.h>
#include <fstream>
#include "dbOperation.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include "localPool.h"
#include "memoryData.h"
#include <boost/filesystem.hpp>
#include "sgeNet.h"
#include "HandleTask.h"
#include <audit.h>
#include "InstDataConverter.h"

extern int keyerror;
extern int show_Num;//最大显示多少
extern int con_state_recv;
//extern int recv_q012;
extern string clientColor;
extern string x07;
extern int delete_db;
extern volatile int baodan_flag, chengjiaodan_flag, hangqing_flag;

extern string monitorType;

extern dataCollection datacollection;
extern ExternInterface externInterface;
int Simulation::qutationNum;

int Simulation::delegationNum;

int Simulation::dealNum;

int Simulation::repRefreshTime;

int Simulation::quoRefreshTime;

int Simulation::kmiRefreshTime;

int Simulation::maxShowNum;

dimC Simulation::dc;

bool isServiceStarted = false;
bool recv_jg_zlc = true;

int countNum = 0;

std::string msgX07 = "";
string synflg = "";
Simulation::Simulation()
{
	dc = dimC();
}

Simulation::~Simulation()
{

}

void Simulation::SaveThread_A(Module* module)
{
	boost::mutex::scoped_lock lock = boost::mutex::scoped_lock(datacollection.saveMutex_A);
	module->save();
	lock.unlock();
}

void Simulation::SaveThread_B(Module* module)
{
	boost::mutex::scoped_lock lock = boost::mutex::scoped_lock(datacollection.saveMutex_B);
	module->save();
	lock.unlock();
}

/**
 * 对返回的报文进行处理，若有不完整的报文，待全部接收后，发送到处理方法
 **/
void Simulation::msgDivision(string& msg)
{
	//会员状态接收
	if (msg.find(CHANGE_INST_STATE_PUSH) != msg.npos)
	{
		con_state_recv = 2;
	}
	//if (msg.find(TRADE_REALTIME_QUOTATION_PUSH) != msg.npos)
	//{
		//recv_q012 = 2;
	//}
	//报文类型
	string x03 = getFieldValue(msg, "X03");
	//报文连续
	string x06 = getFieldValue(msg, "X06");

	//错误报文的丢弃
	if (x03 == "" || x06 == "") return;


	//新框架入口 start----------------------------------------------------------------------------------------------------------------------------------
	bool isIneed = (/*x03 == ORDER_PUSH || x03 == CANCEL_ORDER_PUSH ||*/ x03 == ISSUE_PROCLAIM_PUSH /*|| x03 == CHANGE_MARKET_STATE_PUSH || x03 == CHANGE_INST_STATE_PUSH */ ||
		x03 == TRADER_SELECT_ANSWER || x03 == ISSUE_PROCLAIM_ANSWER || x03 == SELECT_PROCLAIM_ANSWER || x03 == EMERGENCY_ORDER_ANSWER || x03 == TRADER_SIGNOUT_ANSWER);//端午版本暂时做这些，合约市场的因为要刷新右下角时间，
																										 //所以新老框架都需要，但是数据只从新框架推送，老框架只做时间显示那块的逻辑

	if (isIneed || x03 == CHANGE_MARKET_STATE_PUSH || x03 == CHANGE_INST_STATE_PUSH || x03 == INST_GROUP_PUSH)
	{
		Audit::instance()->getAuditJson(string(msg));
		HandleTask::instance()->putInGtpQueue(msg);
		if (isIneed)return;
	}
	//新框架入口 end -----------------------------------------------------------------------------------------------------------------------------------




	if (msg.find(INST_GROUP_PUSH) != msg.npos)
	{
		z_hash_t *hash = z_gtpstr2hash(msg.c_str(), (int)msg.size());
		if (!hash)
		{
			logs(error_, __FUNCTION__ + string("垃圾报文(已丢弃)：") + msg);
			return;
		}

		//将合约组信息解析到datacollection.instGroupMap/ datacollection.mlst去
		string I10 = getFieldValue(msg, "I10");
		string I96 = getFieldValue(msg, "I96");
		z_string_t* zs = zH_strfind_string(hash, "I97");
		string I97 = string2str(zs);
		if (hash)zH_free(hash);


		instGroupMsg ins;
		ins.id = I96;
		ins.name = I97;
		datacollection.instGroupMap[I10] = ins;


		auto it2 = datacollection.mlst.find(I96);
		if (it2 != datacollection.mlst.end())
		{
			it2->second.push_back(I10);
		}
		else
		{
			vector<string> tmp;
			tmp.push_back(I10);
			datacollection.mlst.insert(make_pair(I96, tmp));
		}
		return;
	}

	//登陆成功，初始化线程池
	if ((x03 == TRADER_LOGIN_ANSWER || x03 == MONITOR_LOGIN_ANSWER) && msg.find("X39=RSP000000") != msg.npos)
	{

		map<string, string>::iterator it1 = datacollection.configMap.find("pool_A");
		int a = ModuleUtils::ston(it1->second);
		LocalPool::pool_A = a;
		map<string, string>::iterator it2 = datacollection.configMap.find("pool_A2");
		int b = ModuleUtils::ston(it2->second);
		LocalPool::pool_A2 = b;
		map<string, string>::iterator it3 = datacollection.configMap.find("pool_B");
		int c = ModuleUtils::ston(it3->second);
		LocalPool::pool_B = c;
		map<string, string>::iterator it4 = datacollection.configMap.find("pool_C");
		int d = ModuleUtils::ston(it4->second);
		LocalPool::pool_C = d;
		map<string, string>::iterator it5 = datacollection.configMap.find("pool_D");
		int e = ModuleUtils::ston(it5->second);
		LocalPool::pool_D = e;
		map<string, string>::iterator it6 = datacollection.configMap.find("pool_E");
		int f = ModuleUtils::ston(it6->second);
		LocalPool::pool_E = f;
		map<string, string>::iterator it7 = datacollection.configMap.find("pool_F");
		int g = ModuleUtils::ston(it7->second);
		LocalPool::pool_F = g;

		//后台线程是否启动
		if (!isServiceStarted)
		{
			//成功登陆启动后台线程  启动推送报文 处理推送报文
			externInterface.initial();
			boost::this_thread::sleep(boost::posix_time::milliseconds(1000));//Why?
			isServiceStarted = true;
		}
	}

	string x07 = getFieldValue(msg, "X07");
	//查询应答报文处理
	//连续
	if (x06 == "C")
	{
		Simulation::asynPull(msg, x07, x06);
	}
	else if (x06 == "L")
	{
		if (x07 != "" && x07 == msgX07)
		{
			Simulation::asynPull(msg, x07, x06);
		}
		else
		{
			vector<string> v;   //默认只有一条，直接构建vector开始解析处理
			v.push_back(msg);
			//
			Simulation::distributeMsg(v);
		}
	}
}
void Simulation::asynPull(string &msg, string x07, string x06)
{

	if (msgX07 != "" && x07 == msgX07 && synflg == "O")  //已被超时遗弃了
		return;
	//当前x07与前面x07不一样，唤醒第一次，避免报超时
	if (x07 != msgX07)
	{
		msgX07 = x07;
		boost::mutex::scoped_lock lockT2(datacollection.tradeMutex);
		map<string, map<string, x03Infos>>::iterator ita = datacollection.tradeMesgInfo.find(datacollection.globalUsername);
		if (ita != datacollection.tradeMesgInfo.end())
		{
			//唤醒第一次
			map<string, x03Infos>::iterator it = ita->second.find(x07);
			if (it != ita->second.end())
			{
				it->second.lock->dblmt.lock();
				lockT2.unlock();
				it->second.lock->returnValue = "RSP000000";

				if (!it->second.lock->lockA.owns_lock())
				{
					it->second.lock->mt.unlock();
				}
				else
					it->second.lock->lockA.unlock();
				synflg = it->second.module->getAttribute("synflg");

			}
			else
			{
				synflg = "O";//已经被遗弃了
				return;
			}
		}
		else
		{
			synflg = "O";//已经被遗弃了
			return;
		}
		if (synflg != "N") //同步处理，塞入成堆报文
		{
			vector<string>* vecbuf = new vector<string>();
			Simulation::answerMsgTempM[x07] = vecbuf;
			vecbuf->push_back(msg);
			return;
		}
	}


	//处理报文，第二次唤醒
	if (synflg == "N") //异步处理
	{
		Simulation::asynPullItem(msg, x07, x06); //走异步处理
		return;
	}
	std::vector<string>* vecbuf = Simulation::answerMsgTempM[x07];
	vecbuf->push_back(msg);  //放入报文
	//处理状态为L的报文，清理缓存
	if (x06 == "L")
	{
		Simulation::answerMsgTempM.erase(x07);
		Simulation::distributeMsg(*vecbuf);
		delete vecbuf;
	}
}

void Simulation::asynPullItem(string msg, string x07, string x06)
{
	map<string, map<string, x03Infos>>::iterator ita = datacollection.tradeMesgInfo.find(datacollection.globalUsername);
	map<string, x03Infos>::iterator it = ita->second.find(x07);
	ReadSetAble* mtemp = it->second.mifps;
	ModuleList* mlst = NULL;
	if (mtemp != NULL)
		mlst = dynamic_cast<ModuleList*>(mtemp);
	if (mlst == NULL)
		return;
	Module *module = it->second.module;
	if (module == NULL)
		return;
	std::map<string, string> itemp_tot;
	map<string, Datafield*> dfmap = module->getDatafields();
	map<string, Datafield*>::iterator ittemp = dfmap.begin();
	for (; ittemp != dfmap.end(); ittemp++)  //制定map模板
	{
		itemp_tot[ittemp->first] = "";
	}
	string isClosed = mlst->getTransaction()->getAttribute("isClosed");
	if (isClosed == "Y")  //如果界面已经关闭了则提前唤醒，并不再收取该X07的报文
	{
		synflg = "O";
		it->second.lock->dblmt.unlock();
		return;
	}

	if (!mlst->enableVirtual)
	{
		return;
	}
	string jsonarr = "[";
	vector<string> vB;
	//报文数据可能包含多个报文，分割存入vB
	Simulation::combinateMsgs(vB, msg);

	for (int n = 0; n < vB.size(); ++n)
	{
		std::map<string, string> itemp = itemp_tot; //map 模板拷贝
		vector<string> vC;
		msgToVec(vC, vB[n]);
		size_t len = vC.size();
		for (int n = 0; n < len; n = n + 2)
		{
			if (vC[n].size() > 0 && (vC[n].find("X0") != vC[n].npos || vC[n] == "X39" || vC[n] == "X40"))
				continue;
			//替换单位格式
			replaceFormat_B(vC[n], vC[n + 1]);
			//替换字段名称
			map<string, string>::iterator it = datacollection.gtpFieldMap.find(vC[n]);
			if (it != datacollection.gtpFieldMap.end())
			{
				vC[n] = it->second;
			}
			//设置值						
			itemp[vC[n]] = vC[n + 1];
		}
		if (itemp.size() == 0)
			continue;
		itemp["chk"] = "";
		if (!mlst->disableKeep)
			mlst->vtVec.push_back(itemp);
		jsonarr += Parse::mapToJSON(itemp) + ",";
		//itemp.clear();
	}
	if (jsonarr.size() == 1)
		jsonarr += "]";
	else
		jsonarr.replace(jsonarr.rfind(','), 1, "]");
	int pageNo = -1;
	string pagestr = mlst->getAttribute("pageno");
	if (pagestr != "")
		pageNo = ModuleUtils::ston(pagestr);
	pageNo++;
	pagestr = itos(pageNo);
	mlst->setAttribute("pageno", pagestr);
	pagestr = "setModify_APPEND" + pagestr;

	eComponet ec;
	ec.action = pagestr;
	ec.pctxid = mlst->getTransaction()->_pageCtx->getpctxid();
	ec.uri = mlst->getUrl();
	ec.value = jsonarr;

	PageInfoSwitch* pis = dynamic_cast<PageInfoSwitch*>(mlst->getTransaction()->_pageCtx->getUiSupport());
	if (pis != NULL)
		pis->infoswitch->pushAsyn(ec);
	if (x06 == "L")
	{
		mlst->setAttribute("pageno", "");
		it->second.lock->dblmt.unlock();
	}
}

/**
 * 对得到的完整响应报文分发到不同线程进行处理
 **/
void Simulation::distributeMsg(vector<string>& msgs)
{
	size_t s = msgs.size();
	string msg = "";
	for (size_t m = 0; m < s; m++)
	{
		if (m == 0)
		{
			msg = msgs[0];
		}
		else {
			msg += "_###_" + msgs[m];
		}
	}
	//登陆重连的错误信息显示
	if (msg.find("RSP013006") != msg.npos)
	{
		map<string, PageContext*>::iterator it = datacollection.backTradePctx.find("tolbar");
		if (it != datacollection.backTradePctx.end())
		{
			it->second->getTransaction()->service(string("disconnect"), string(""));
		}
		return;
	}

	string log_x07 = getFieldValue(msg, "X07");

	string x03a = getFieldValue(msgs[0], "X03");
	//M991的错误报文解析
	if (x03a == UNIVERSAL_ERROR_ANSWER)
	{
		//TODO:
		string title = "提示";
		const char *ttc = title.c_str();
		string em = "交易核心报错:" + getFieldValue(msgs[0], "X40") + "  请重新登录！";
		const char *c = em.c_str();

		MessageBoxA(NULL, c, ttc, MB_OK);
		ModuleUtils::restart();
		return;
	}
	if (x03a == "")
	{
		return;
	}
	if (x03a == CANCEL_ORDER_PUSH || x03a == ORDER_PUSH)
	{
		LocalPool::pool_A.schedule(boost::bind(Simulation::tpoolProcess, "delgte", x03a, msg));
	}
	else if (x03a == ORDER_DEAL_PUSH)
	{
		LocalPool::pool_A2.schedule(boost::bind(Simulation::tpoolProcess, "delgte", x03a, msg));

	}
	else if (x03a == TRADE_REALTIME_QUOTATION_PUSH)//行情推送
	{
		//行情处理
		//行情在api线程处理，优点是1.简化线程模型，维护简单 2.和合约在一个线程处理，可以保证先处理行情再处理合约 3.行情顺序不会乱
		//缺点是影响性能，甚至可能在单量大时严重影响性能导致界面卡顿。若出现这种情况，行情要恢复多线程处理，同时对合约的处理要做好增加默认行情的逻辑
		//暂时先按简单的方式做，符合简化线程模型的期望目标
		tpoolProcess("mktinf", TRADE_REALTIME_QUOTATION_PUSH, msg);
		//LocalPool::pool_F.schedule(boost::bind(Simulation::tpoolProcess, "mktinf", TRADE_REALTIME_QUOTATION_PUSH, msg));
		//时间显示
		LocalPool::pool_B.schedule(boost::bind(Simulation::tpoolProcess, "tolbar", TRADE_REALTIME_QUOTATION_PUSH, msg));
	}
	else if (x03a == SELECT_REALTIME_QUOTATION_ANSWER)//行情查询
	{
		LocalPool::pool_C.schedule(boost::bind(Simulation::tpoolProcess, "xjshi", SELECT_REALTIME_QUOTATION_ANSWER, msg));
	}
	else if (x03a == ISSUE_PROCLAIM_PUSH)//公告
	{
		LocalPool::pool_B.schedule(boost::bind(Simulation::tpoolProcess, "tolbar", ISSUE_PROCLAIM_PUSH, msg));
	}
	else if (x03a == CHANGE_INST_STATE_PUSH)//合约状态
	{
		LocalPool::pool_B.schedule(boost::bind(Simulation::tpoolProcess, "tolbar", CHANGE_INST_STATE_PUSH, msg));
	}
	else if (x03a == INST_MESSAGE_PUSH)
	{
		//NOTE:将合约放到API回调线程处理的原因：
		//1)保证合约在成交流之前处理
		//2)保证合约没有发生更新时其在MEM_DATA的映射每次登录都一致（前提：服务每次推送合约的顺序一致
		tpoolProcess("tolbar", INST_MESSAGE_PUSH, msg);
		tpoolProcess("mktinf", INST_MESSAGE_PUSH, msg);
		tpoolProcess("condet", INST_MESSAGE_PUSH, msg);//交割行情收到合约后，要显示默认的交割行情数据。
		pushBaseData(msg, "instInfos");
		//LocalPool::pool_B.schedule(boost::bind(Simulation::tpoolProcess, "tolbar", INST_MESSAGE_PUSH, msg));
	}
	else if (x03a == MARKET_MESSAGE_PUSH)
	{
		//放在API线程处理的理由同上
		tpoolProcess("tolbar", MARKET_MESSAGE_PUSH, msg);
		//LocalPool::pool_B.schedule(boost::bind(Simulation::tpoolProcess, "tolbar", MARKET_MESSAGE_PUSH, msg));
		//TODO: 是否需要pushBaseData
	}
	else if (x03a == VARIETY_MESSAGE_PUSH)
	{
		//放在API线程处理的理由同上
		tpoolProcess("tolbar", VARIETY_MESSAGE_PUSH, msg);
		pushBaseData(msg, "varietyInfos");
		//LocalPool::pool_B.schedule(boost::bind(Simulation::tpoolProcess, "tolbar", VARIETY_MESSAGE_PUSH, msg));
	}
	else if (x03a == CHANGE_MARKET_STATE_PUSH)
	{
		LocalPool::pool_B.schedule(boost::bind(Simulation::tpoolProcess, "tolbar", CHANGE_MARKET_STATE_PUSH, msg));
	}
	else if (x03a == DEFER_FEE_RATE_PAY_DIRECTION_PUSH)//递延费率支付方向
	{
		//放在API回调线程处理，简化线程模型，如果后续测试性能有影响，则恢复使用pool_B处理，其他代码不用变化
		tpoolProcess("condet", DEFER_FEE_RATE_PAY_DIRECTION_PUSH, msg);
		//LocalPool::pool_B.schedule(boost::bind(Simulation::tpoolProcess, "condet", DEFER_FEE_RATE_PAY_DIRECTION_PUSH, msg));
	}
	else if (x03a == DELIVERY_REALTIME_QUOTATION_PUSH)//交割申报量及中立仓申报量
	{
		//放在API回调线程处理，简化线程模型，如果后续测试性能有影响，则恢复使用pool_B处理，其他代码不用变化
		tpoolProcess("condet", DELIVERY_REALTIME_QUOTATION_PUSH, msg);
		//LocalPool::pool_B.schedule(boost::bind(Simulation::tpoolProcess, "condet", DELIVERY_REALTIME_QUOTATION_PUSH, msg));
	}
	else if (x03a == DELIVERY_ORDER_DEAL_PUSH)
	{
		size_t o05indexa = msg.find("O05");
		size_t equalSignIndexa = msg.find("=", o05indexa);
		size_t dotIndexa = msg.find(",", o05indexa);
		string o05a = msg.substr(equalSignIndexa + 1, dotIndexa - equalSignIndexa - 1);
		if (o05a == "0")     //交割成交单
		{
			LocalPool::pool_A2.schedule(boost::bind(Simulation::tpoolProcess, "seddis", DELIVERY_ORDER_DEAL_PUSH, msg));
		}
		else if (o05a == "1")  //中立仓成交单
		{
			LocalPool::pool_A2.schedule(boost::bind(Simulation::tpoolProcess, "middis", DELIVERY_ORDER_DEAL_PUSH, msg));
		}
	}
	else if (x03a == DELIVERY_ORDER_PUSH || x03a == CANCEL_DELIVERY_ORDER_PUSH)
	{
		LocalPool::pool_A.schedule(boost::bind(Simulation::tpoolProcess, "seddis", x03a, msg));
	}
	else if (x03a == NEUTRALITY_ORDER_PUSH || x03a == CANCEL_NEUTRALITY_ORDER_PUSH)
	{
		LocalPool::pool_A.schedule(boost::bind(Simulation::tpoolProcess, "middis", x03a, msg));
	}
	else
	{		//对查询一次性返回大报文（最大8192k）	
		if (msgs.size() == 1)
		{
			LocalPool::pool_C.schedule(boost::bind(Simulation::tpoolProcess, "", x03a, msg));
		}
		else if (msgs.size() > 1)
		{
			boost::thread sessionMngThread(&Simulation::multiProcess, x03a, msgs);
		}
	}
}
/**
  应用于查询的批次回报
*/
void Simulation::multiProcess(string x03, vector<string> vA)
{
	try
	{
		boost::mutex::scoped_lock lockT(datacollection.tradeMutex);
		string x07 = getFieldValue(vA[0], "X07");
		map<string, x03Infos>::iterator it = datacollection.tradeMesgInfo.find(datacollection.globalUsername)->second.find(x07);
		if (it == datacollection.tradeMesgInfo.find(datacollection.globalUsername)->second.end())
		{
			logs(error_, "延时回报" + x03 + "vector被丢弃");
			return;
		}

		x03Infos x03info = it->second;
		boost::mutex::scoped_lock lockM(x03info.module->getMutex());
		lockT.unlock();
		ModuleList* mlist = NULL;
		if (x03info.mifps != NULL)
		{
			mlist = dynamic_cast<ModuleList*>(x03info.mifps);
			if (mlist == NULL)
				return;
			mlist->clear();
		}
		x03info.pgcontext->getPersistence()->begin();
		map<string, Datafield*> datafields = x03info.module->getDatafields();
		std::map<string, string> itemp;
		x03info.pgcontext->getPersistence()->del(x03info.tableName);
		for (int m = 0; m < vA.size(); ++m)
		{
			vector<string> vB;
			//报文数据可能包含多个报文，分割存入vB
			Simulation::combinateMsgs(vB, vA[m]);
			for (int n = 0; n < vB.size(); ++n)
			{
				//保存前先清空值
				x03info.module->clear();
				ModuleUtils::clear(x03info.module);
				vector<string> vC;
				msgToVec(vC, vB[n]);
				size_t len = vC.size();
				for (size_t n = 0; n < len; n = n + 2)
				{
					if (vC[n].size() > 2 && (vC[n].find("X0") != vC[n].npos || vC[n] == "X39" || vC[n] == "X40"))
						continue;
					//替换单位格式
					replaceFormat_B(vC[n], vC[n + 1]);
					//替换字段名称
					map<string, string>::iterator it = datacollection.gtpFieldMap.find(vC[n]);
					if (it != datacollection.gtpFieldMap.end())
					{
						vC[n] = it->second;
					}
					//设置值
					if (mlist && mlist->enableVirtual)
					{

						itemp[vC[n]] = vC[n + 1];
					}
					else
					{
						if (datafields.find(vC[n]) != datafields.end())
						{
							datafields[vC[n]]->setValue(vC[n + 1]);
						}
					}
				}
				if (mlist && mlist->enableVirtual)
				{
					if (itemp.size() == 0)
						continue;
					itemp["chk"] = "";
					mlist->vtVec.push_back(itemp);
					itemp.clear();
					continue;
				}
				if (x03 != CANCEL_ORDER_ANSWER && x03 != CANCEL_DELIVERY_ORDER_ANSWER && x03 != CANCEL_NEUTRALITY_ORDER_ANSWER && x03 != CANCEL_EMERGENCY_ORDER_ANSWER && x03 != CANCEL_FORCE_LIQUIDATION_ANSWER && x03 != FORCE_CANCEL_ORDER_ANSWER)//撤单操作不存入数据库
				{
					x03info.pgcontext->getPersistence()->save(x03info.pa);
				}
			}
		}
		x03info.pgcontext->getPersistence()->commit();
		lockM.unlock();
		boost::mutex::scoped_lock lockT2(datacollection.tradeMutex);
		map<string, map<string, x03Infos>>::iterator ita = datacollection.tradeMesgInfo.find(datacollection.globalUsername);
		if (ita != datacollection.tradeMesgInfo.end())
		{
			//唤醒
			map<string, x03Infos>::iterator it = ita->second.find(x07);
			it->second.lock->dblmt.unlock();
		}
	}
	catch (exception e)
	{
		logs(warning_, funcx + e.what()+x03);
	}

}

bool Simulation::isMultiMessages(string& msg) {
	return msg.find("_###_") != msg.npos;
}

bool Simulation::handleInstQuotationRsp(string & code, string& msg) {
	string x39 = getFieldValue(msg, "X39");
	string x40 = getFieldValue(msg, "X40");
	if (x39 == "RSP000000")
	{
		parseQ(code, "", msg, NULL, NULL, NULL);
	}

	boost::mutex::scoped_lock lockT(datacollection.tradeMutex);
	string x07 = getFieldValue(msg, "X07");
	map<string, x03Infos>::iterator it = datacollection.tradeMesgInfo.find(datacollection.globalUsername)->second.find(x07);
	if (it != datacollection.tradeMesgInfo.find(datacollection.globalUsername)->second.end())
	{
		it->second.lock->returnValue = x39 + "#" + x40; 
		if (isMultiMessages(msg)) {
			it->second.lock->dblmt.unlock();
		}
		else {
			if (!it->second.lock->lockA.owns_lock())
			{
				it->second.lock->mt.unlock();
			}
			else
				it->second.lock->lockA.unlock();
		}
	}
	return true;
}

/**
 * 线程池中线程对每个报文执行此方法 业务模型名，X03 报文
 **/
void Simulation::tpoolProcess(string name, string code, string msg)
{
	try {//撤单应答报文的处理  //todo 对收到其他交易员的撤单应答报文的匹配处理
		if (code == CANCEL_ORDER_ANSWER || code == CANCEL_DELIVERY_ORDER_ANSWER || code == CANCEL_NEUTRALITY_ORDER_ANSWER)
		{
			string x07 = getFieldValue(msg, "X07");
			string con = getFieldValue(msg, "O00");
			code = code + "_" + con;
			boost::mutex::scoped_lock lockT(datacollection.tradeMutex);
			x03Infos x03info;
			map<string, map<string, x03Infos>>::iterator it_m = datacollection.tradeMesgInfo.find(datacollection.globalUsername);
			if (it_m != datacollection.tradeMesgInfo.end())
			{
				map<string, x03Infos>::iterator it_n = it_m->second.find(x07);
				if (it_n != it_m->second.end())
				{
					x03info = it_n->second;
				}
				else {
					return;
				}
			}
			else {
				return;
			}
			lockT.unlock();
		}


		if (code == "" || msg == "")
		{
			return;
		}
		//推送报文处理
		if (code == ORDER_DEAL_PUSH || code == ORDER_PUSH || code == TRADE_REALTIME_QUOTATION_PUSH || code == ISSUE_PROCLAIM_PUSH || code == DEFER_FEE_RATE_PAY_DIRECTION_PUSH || code == DELIVERY_REALTIME_QUOTATION_PUSH
			|| code == CHANGE_INST_STATE_PUSH || code == DELIVERY_ORDER_DEAL_PUSH || code == DELIVERY_ORDER_PUSH || code == CANCEL_DELIVERY_ORDER_PUSH || code == NEUTRALITY_ORDER_PUSH || code == CANCEL_NEUTRALITY_ORDER_PUSH
			|| code == MARKET_MESSAGE_PUSH || code == CHANGE_MARKET_STATE_PUSH || code == INST_MESSAGE_PUSH || code == VARIETY_MESSAGE_PUSH || code == CANCEL_ORDER_PUSH)
		{
			map<string, PageContext*>::iterator it = datacollection.backTradePctx.find(name);
			if (it != datacollection.backTradePctx.end())
			{
				it->second->getTransaction()->service(code, msg);
			}
			return;
		}

		if (code == MONITOR_LOGIN_ANSWER) {//监控员登录

			if (msg.find("X39=RSP000000") != msg.npos)
			{
				SgeNet::instance()->isLogined = true;
			}
			logs(info_, "login--07--成功收到应答");
			Audit::instance()->getAuditJson(msg);

			string userID = getFieldValue(msg, "G20");
			map<string, LockUnit*>::iterator it = datacollection.loginLockInfo.find(userID);
			if (it != datacollection.loginLockInfo.end())
			{
				it->second->returnValue = msg;
				if (!it->second->lockA.owns_lock())
				{
					it->second->mt.unlock();
				}
				else
				{
					it->second->lockA.unlock();
				}
			}
		}
		else if (code == MONITOR_LOGINOUT_ANSWER) {//监控员退出
			Audit::instance()->getAuditJson(msg);
			string userID = getFieldValue(msg, "G20");
			map<string, LockUnit*>::iterator it = datacollection.logoutLockInfo.find(userID);
			if (it != datacollection.logoutLockInfo.end())
			{
				it->second->returnValue = msg;
				if (!it->second->lockA.owns_lock())
				{
					it->second->mt.unlock();
				}
				else
					it->second->lockA.unlock();
			}
		}
		else if (code == SELECT_REALTIME_QUOTATION_ANSWER) {//合约行情查询返回		
			handleInstQuotationRsp(code, msg);
		}
		else {
			string x39 = getFieldValue(msg, "X39");
			string x40 = getFieldValue(msg, "X40");
			if (x39 == "RSP000000")
			{
				if (code == SELECT_NEUTRALITY_ANSWER || code == SELECT_DELIVERY_ANSWER || code == SELECT_DELIVERY_DEAL_ANSWER || code == SELECT_SEATHOLD_ANSWER || code == SELECT_SEATCUST_ANSWER || code == SELECT_ORDER_ANSWER || code == SELECT_DEAL_ORDER_ANSWER || code == SELECT_PROCLAIM_ANSWER
					|| code == SELECT_EMERGENCY_ORDER_ANSWER || code == SELECT_FUND_SHORTAGE_ANSWER || code == SELECT_SEAT_OVERPOSITION_ANSWER || code == SELECT_CUST_OVERPOSITION_ANSWER || code == SELECT_CUSTHOLD_ANSWER || code == SELECT_CUSTSTOCK_ANSWER || code == TRADER_SELECT_ANSWER)
				{
					if (msg.find("[") == msg.npos)
					{
						x39 = "RSP999998";
						x40 = "查询结果为空";
					}
				}
				parseAnswerMsg(code, msg);
			}
			boost::mutex::scoped_lock lockT(datacollection.tradeMutex); //针对请求类报文操作Map加锁

			map<string, map<string, x03Infos>>::iterator ita = datacollection.tradeMesgInfo.find(datacollection.globalUsername);
			if (ita != datacollection.tradeMesgInfo.end())
			{
				string x07 = getFieldValue(msg, "X07");
				if (code == CANCEL_ORDER_ANSWER)//撤单回报
				{
					string billNo = getFieldValue(msg, "O00");
					string key = x07;//"T211_" + billNo;
					map<string, x03Infos>::iterator it = ita->second.find(key);
					if (it != ita->second.end())
					{
						it->second.lock->returnValue = x39 + "#" + x40;
						if (!it->second.lock->lockA.owns_lock())
						{
							it->second.lock->mt.unlock();
						}
						else
							it->second.lock->lockA.unlock();
					}
				}
				else if (code == CHANGE_INST_STATE_ANSWER)//合约状态改变回报
				{
					string instID = getFieldValue(msg, "I10");
					string key = x07;//"B181_" + instID;
					map<string, x03Infos>::iterator it = ita->second.find(key);
					if (it != ita->second.end())
					{
						//it->second.lock->returnValue = x39 + "#" + instID + x40;
						it->second.lock->returnValue = x39 + "#" + InstDataConverter::InstId2Code(instID.c_str()) + x40;
						if (!it->second.lock->lockA.owns_lock())
						{
							it->second.lock->mt.unlock();
						}
						else
							it->second.lock->lockA.unlock();
					}
				}
				else {
					map<string, x03Infos>::iterator it = ita->second.find(x07);
					if (it != ita->second.end())
					{
						it->second.lock->returnValue = x39 + "#" + x40;
						if (!it->second.lock->lockA.owns_lock())
						{
							it->second.lock->mt.unlock();
						}
						else
							it->second.lock->lockA.unlock();
					}
				}
			}
		}
	}
	catch (exception e)
	{
		logs(warning_, funcx + e.what()+msg);
	}
}

/**
 * 解析应答式响应整体报文
 **/
void Simulation::parseAnswerMsg(string x03, string tradeMsg)
{
	try {
		string key = getFieldValue(tradeMsg, "X07");

		Audit::instance()->getAuditJson(tradeMsg);

		boost::mutex::scoped_lock lockT(datacollection.tradeMutex); //针对请求类报文操作Map加锁
		long timeX1 = clock();
		map<string, x03Infos>::iterator it = datacollection.tradeMesgInfo.find(datacollection.globalUsername)->second.find(key);
		if (it == datacollection.tradeMesgInfo.find(datacollection.globalUsername)->second.end())
		{
			logs(error_, "延时回报" + key + "被丢弃");
			return;
		}
		if (x03 == "T611" || x03 == "T621")
		{
			//复核通知，不做入库处理
			return;
		}
		x03Infos x03info = it->second;
		boost::mutex::scoped_lock lockM(x03info.module->getMutex());
		long timeX = clock();
		lockT.unlock();
		ModuleList* mlist = NULL;
		if (x03info.mifps != NULL)
		{
			mlist = dynamic_cast<ModuleList*>(x03info.mifps);
			if (mlist == NULL)
				return;
			mlist->clear();
			if (tradeMsg.find("[") == tradeMsg.npos)
			{
				return;
			}
		}
		logs(debug_, key + "-------parseAnswerMsg01--");
		x03info.pgcontext->getPersistence()->begin();
		logs(debug_, key + "-------parseAnswerMsg01--" + x03info.tableName);
		x03info.pgcontext->getPersistence()->del(x03info.tableName);
		logs(debug_, key + "-------parseAnswerMsg01********--" + x03info.tableName);
		map<string, Datafield*> datafields = x03info.module->getDatafields();
		logs(debug_, key + "-------parseAnswerMsg02");
		vector<string> vA;
		splitCombineMsg(tradeMsg, vA);
		logs(debug_, key + "-------parseAnswerMsg03");

		Module *module = it->second.module;
		if (module == NULL)
			return;
		std::map<string, string> itemp_tot;
		map<string, Datafield*> dfmap = module->getDatafields();
		map<string, Datafield*>::iterator ittemp = dfmap.begin();
		for (; ittemp != dfmap.end(); ittemp++)  //制定map模板
		{
			itemp_tot[ittemp->first] = "";
		}

		for (int m = 0; m < vA.size(); ++m)
		{
			std::map<string, string> itemp = itemp_tot; //拷贝map
			vector<string> vB;
			//报文数据可能包含多个报文，分割存入vB
			Simulation::combinateMsgs(vB, vA[m]);
			for (int n = 0; n < vB.size(); ++n)
			{
				//保存前先清空值
				x03info.module->clear();
				ModuleUtils::clear(x03info.module);
				vector<string> vC;
				msgToVec(vC, vB[n]);
				size_t len = vC.size();
				for (size_t n = 0; n < len; n = n + 2)
				{
					if (vC[n].size() > 0 && (vC[n].find("X0") != vC[n].npos || vC[n] == "X39" || vC[n] == "X40"))
						continue;
					//替换单位格式
					replaceFormat_B(vC[n], vC[n + 1]);
					//替换字段名称
					map<string, string>::iterator it = datacollection.gtpFieldMap.find(vC[n]);
					if (it != datacollection.gtpFieldMap.end())
					{
						vC[n] = it->second;
					}
					//设置值
					if (mlist && mlist->enableVirtual)
					{

						itemp[vC[n]] = vC[n + 1];
					}
					else
					{
						if (datafields.find(vC[n]) != datafields.end())
						{
							datafields[vC[n]]->setValue(vC[n + 1]);
						}
					}
				}
				if (mlist && mlist->enableVirtual)
				{
					if (itemp.size() == 0)
						continue;
					itemp["chk"] = "";
					mlist->vtVec.push_back(itemp);
					//itemp.clear();
					continue;
				}
				if (x03 != CANCEL_ORDER_ANSWER && x03 != CANCEL_DELIVERY_ORDER_ANSWER && x03 != CANCEL_NEUTRALITY_ORDER_ANSWER && x03 != CANCEL_EMERGENCY_ORDER_ANSWER && x03 != CANCEL_FORCE_LIQUIDATION_ANSWER && x03 != FORCE_CANCEL_ORDER_ANSWER)//撤单操作不存入数据库
				{
					x03info.pgcontext->getPersistence()->save(x03info.pa);
				}
			}
		}
		x03info.pgcontext->getPersistence()->commit();
		logs(debug_, x03 + "-------parseAnswerMsg04");
	}
	catch (exception e)
	{
		logs(warning_, funcx + e.what()+tradeMsg);
	}
}

/**
 * 推送服务获取报文后调用此方法
 **/
bool Simulation::pushAnswer(PageContext *context, ModuleList *mifps, Module *module, string& tradeMsg, string& tradeType)
{
	string I10 = getFieldValue(tradeMsg, "I10");
	if (tradeType != ORDER_DEAL_PUSH && tradeType != ORDER_PUSH && tradeType != CANCEL_ORDER_PUSH && tradeType != CANCEL_DELIVERY_ORDER_PUSH && tradeType != CANCEL_NEUTRALITY_ORDER_PUSH && tradeType != DELIVERY_ORDER_PUSH && tradeType != DELIVERY_ORDER_DEAL_PUSH && tradeType != NEUTRALITY_ORDER_PUSH)//这两个根据合约号分类存储
	{
		I10 = "";
	}

	try {
		//对响应报文进行解析更换格式后的报文
		string parseMsg;
		if (tradeType == TRADE_REALTIME_QUOTATION_PUSH)
		{
			parseQ(tradeType, I10, tradeMsg, context, mifps, module);
		}
		else if (tradeType == MARKET_MESSAGE_PUSH || tradeType == CHANGE_MARKET_STATE_PUSH || tradeType == INST_MESSAGE_PUSH || tradeType == CHANGE_INST_STATE_PUSH || tradeType == VARIETY_MESSAGE_PUSH
			|| tradeType == DELIVERY_REALTIME_QUOTATION_PUSH || tradeType == ISSUE_PROCLAIM_PUSH || tradeType == DEFER_FEE_RATE_PAY_DIRECTION_PUSH || tradeType == ORDER_DEAL_PUSH || tradeType == ORDER_PUSH
			|| tradeType == CANCEL_ORDER_PUSH || tradeType == DELIVERY_ORDER_DEAL_PUSH)
		{

			parseOrdinaryPushMsg(context, mifps, module, tradeMsg, tradeType, I10);
		}
		else if (tradeType == DELIVERY_ORDER_PUSH || tradeType == NEUTRALITY_ORDER_PUSH) {
			string mmm = "";
			vector<string> vvv;
			splitCombineMsg(tradeMsg, vvv);
			for (int m = 0; m < vvv.size(); ++m)
			{
				string msg = Simulation::T092_T122(vvv[m]);
				if (m == 0)
				{
					mmm = msg;
				}
				else {
					mmm += "_###_";
					mmm += msg;
				}
			}
			parseOrdinaryPushMsg(context, mifps, module, mmm, tradeType, I10);
		}
		else if (tradeType == CANCEL_DELIVERY_ORDER_PUSH || tradeType == CANCEL_NEUTRALITY_ORDER_PUSH)
		{
			string mmm = "";
			vector<string> vvv;
			splitCombineMsg(tradeMsg, vvv);
			for (int m = 0; m < vvv.size(); ++m)
			{
				string msg = Simulation::T092_T122(vvv[m]);
				if (m == 0)
				{
					mmm = msg;
				}
				else {
					mmm += "_###_";
					mmm += msg;
				}
			}
			parseOrdinaryPushMsg(context, mifps, module, mmm, tradeType, I10);
		}
		return true;
	}
	catch (exception e)
	{
		logs(warning_, funcx + e.what()+tradeMsg);
		return false;
	}
}

//todo: 和红马甲相关代码合并，消除重复
bool Simulation::addInstCode2Quotation(string& instId, map<string, string>& map)
{
	if (instId == "")
	{
		logs(error_, "addInstCode2Quotation 出错，instId为空");
		map.insert(pair<string, string>("instCode", ""));
		return false;
	}
	string instCode = InstDataConverter::InstId2Code(instId.c_str());
	if (instCode == "")
	{
		logs(warning_, "addInstCode2Quotation 出错，调用InstDataConverter::InstId2Code 失败，返回值为空");
		map.insert(pair<string, string>("instCode", ""));
		return false;
	}
	auto ret = map.insert(pair<string, string>("instCode", instCode));
	return ret.second;
	//return true;
}

//bool Simulation::addInstCode2DF(string& instId, map<string, Datafield*>& datafields) 
//{
//	if (instId == "")
//	{
//		logs(error_, "addInstCode2DF 出错，instId为空");
//		datafields["instCode"]->setValue("");
//		return false;
//	}
//	string instCode = InstDataConverter::InstId2Code(instId.c_str());
//	if (instCode == "")
//	{
//		logs(error_, "addInstCode2DF 出错，调用InstDataConverter::InstId2Code 失败，返回值为空");
//		datafields["instCode"]->setValue("");
//		return false;
//	}
//	datafields["instCode"]->setValue(InstDataConverter::InstId2Code(instId.c_str()));
//	return true;
//}


//解析行情格式数据
void Simulation::parseQ(string code, string subcode, string &messages, PageContext *context, ModuleList *mifps, Module *module)
{
	string buyPrice[] = { "buyone","buytwo","buythr","buyfou","buyfiv","buysix","buysev","buyeig","buynin","buyten" };
	string buyCount[] = { "bunufi","bunuse","bunuth","bunufo","bunufv","bunsix","bunsev","buneig","bunnin","bunten" };
	string salePrice[] = { "selone","seltwo","selthr","selfou","selfiv","selsix","selsev","seleig","selnin","selten" };
	string saleCount[] = { "senufi","senuse","senuth","senufo","senufv","senusx","sensev","senuei","senuni","senten" };
	try {
		x03Infos x03info;
		map<string, Datafield*> datafields;
		boost::mutex::scoped_lock lockM;
		string x07info = getFieldValue(messages, "X07");
		if (code == SELECT_REALTIME_QUOTATION_ANSWER)
		{
			boost::mutex::scoped_lock lockT(datacollection.tradeMutex);
			map<string, x03Infos>::iterator it = datacollection.tradeMesgInfo.find(datacollection.globalUsername)->second.find(x07info);
			if (it == datacollection.tradeMesgInfo.find(datacollection.globalUsername)->second.end())
			{
				logs(error_, "延时回报" + code + "vector被丢弃");
				return;
			}
			x03info = it->second;
			lockM = boost::mutex::scoped_lock(x03info.module->getMutex());
			x03info.pgcontext->getPersistence()->del(x03info.tableName);
			datafields = x03info.module->getDatafields();
		}

		vector<string> vA;
		splitCombineMsg(messages, vA);
		size_t lenA = vA.size();
		string q012time = "";
		for (size_t i = 0; i < lenA; ++i)
		{
			if (vA[i].find("Q52") != vA[i].npos)
			{
				size_t q52_s = vA[i].find("[");
				size_t q52_e = vA[i].rfind("]");
				string Q52 = vA[i].substr(q52_s + 1, q52_e - q52_s - 1);
				string common_partA = (q52_s - 4 != 0) ? vA[i].substr(0, q52_s - 5) : "";
				string common_partB = (q52_e + 1 != vA[i].size()) ? vA[i].substr(q52_e + 2) : "";
				string common_A = common_partA + "," + common_partB;

				size_t q52sub_s = Q52.find("{");
				size_t q52sub_m;
				size_t q52sub_e;
				while (q52sub_s != Q52.npos)
				{
					if (code == SELECT_REALTIME_QUOTATION_ANSWER)
					{
						x03info.module->clear();
					}
					q52sub_m = Q52.find("]", q52sub_s);
					q52sub_e = Q52.find("}", q52sub_m);
					//Q52中单个｛｝数据
					string Q52_item = Q52.substr(q52sub_s + 1, q52sub_e - q52sub_s - 1);
					size_t Q00index = Q52_item.find("Q00");
					Q52_item = Q52_item.erase(Q00index, 4);
					const char * q52 = Q52_item.c_str();
					char decodeAry[8192] = { 0 };
					int m = 0;
					while (*q52 != '\0')
					{
						if (*q52 != '{' && *q52 != '}' && *q52 != '[' && *q52 != ']')
						{
							decodeAry[m] = *q52;
							m++;
						}
						q52++;
					}
					Q52_item = decodeAry;

					string singlemsg = common_A + "," + Q52_item;

					int buyPrice_f = 0;
					int buyCount_f = 0;
					int salePrice_f = 0;
					int saleCount_f = 0;
					vector<string> vB;
					msgToVec(vB, singlemsg);
					size_t len = vB.size();
					map<string, string> mapA;
					for (size_t n = 0; n < len; n = n + 2)
					{
						if (code == SELECT_REALTIME_QUOTATION_ANSWER)
						{
							replaceFormat_B(vB[n], vB[n + 1]);
						}
						else if (code == TRADE_REALTIME_QUOTATION_PUSH)
						{
							replaceFormat_B(vB[n], vB[n + 1]);
						}
						if (vB[n] == "Q21")
						{
							vB[n] = buyPrice[buyPrice_f];
							buyPrice_f++;
						}
						else if (vB[n] == "Q22")
						{
							vB[n] = buyCount[buyCount_f];
							buyCount_f++;
						}
						else if (vB[n] == "Q23")
						{
							vB[n] = salePrice[salePrice_f];
							salePrice_f++;
						}
						else if (vB[n] == "Q24")
						{
							vB[n] = saleCount[saleCount_f];
							saleCount_f++;
						}
						else {
							map<string, string>::iterator it = datacollection.gtpFieldMap.find(vB[n]);
							if (it != datacollection.gtpFieldMap.end())
							{
								vB[n] = it->second;
							}
						}

						if (code == SELECT_REALTIME_QUOTATION_ANSWER)
						{
							if (datafields.find(vB[n]) != datafields.end())
							{
								datafields[vB[n]]->setValue(vB[n + 1]);
								//TODO: 优化addInstCode2DF和addInstCode2Quotation
								if (vB[n] == "concod")
								{
									if (addInstCode2DF(vB[n + 1], datafields) == false)
									{
										logs(warning_, "addInstCode2DF 失败");
									}
								}
							}
						}
						else if (code == TRADE_REALTIME_QUOTATION_PUSH)
						{
							mapA.insert(pair<string, string>(vB[n], vB[n + 1]));
							if (vB[n] == "mardat" && q012time == "")
								q012time += vB[n + 1];
							if (vB[n] == "martim" && q012time.length() == 8)
								q012time += " " + vB[n + 1];
							if (vB[n] == "concod")
							{
								if (addInstCode2Quotation(vB[n + 1], mapA) == false)
								{
									logs(warning_, "addInstCode2Quotation 失败");
								}
							}
						}
					}
					//特殊处理涨跌幅
					map<string, string>::iterator itQ29 = mapA.find("updora");
					map<string, string>::iterator itQ28 = mapA.find("updown");
					if (itQ29 != mapA.end() && itQ28 != mapA.end())
					{
						string Q28 = itQ28->second;
						string Q29 = itQ29->second;
						if (Q28.length() > 0 && Q28.length() > 0)
						{
							if (Q28[0] == '-' && Q29[0] != '-') //追加“-”
							{
								mapA["updora"] = "-" + Q29;
							}
						}
					}
					if (code == SELECT_REALTIME_QUOTATION_ANSWER)
					{
						string Q28 = datafields["updown"]->getValue();
						string Q29 = datafields["updora"]->getValue();
						if (Q28.length() > 0 && Q28.length() > 0)
						{
							if (Q28[0] == '-' && Q29[0] != '-') //追加“-”
							{
								datafields["updora"]->setValue("-" + Q29);
							}
						}
						x03info.pgcontext->getPersistence()->save(x03info.pa);
					}
					else if (code == TRADE_REALTIME_QUOTATION_PUSH)
					{
						storeQ12Msg(context, mifps, module, mapA, subcode);
					}
					//开始寻找下一个Q52项
					q52sub_s = Q52.find("{", q52sub_e);
				}
			}
			else {
				if (code == SELECT_REALTIME_QUOTATION_ANSWER)
				{
					x03info.module->clear();
				}
				string Q52_item = messages;
				size_t Q00index = Q52_item.find("Q00");
				Q52_item = Q52_item.erase(Q00index, 4);

				const char * q52 = Q52_item.c_str();
				char decodeAry[8192] = { 0 };
				int m = 0;
				while (*q52 != '\0')
				{
					if (*q52 != '{' && *q52 != '}' && *q52 != '[' && *q52 != ']')
					{
						decodeAry[m] = *q52;
						m++;
					}
					q52++;
				}

				Q52_item = decodeAry;

				int buyPrice_f = 0;
				int buyCount_f = 0;
				int salePrice_f = 0;
				int saleCount_f = 0;
				vector<string> vB;
				msgToVec(vB, Q52_item);
				size_t len = vB.size();
				map<string, string> mapA;
				for (size_t n = 0; n < len; n = n + 2)
				{
					if (code == SELECT_REALTIME_QUOTATION_ANSWER)
					{
						replaceFormat_B(vB[n], vB[n + 1]);
					}
					else if (code == TRADE_REALTIME_QUOTATION_PUSH)
					{
						replaceFormat_B(vB[n], vB[n + 1]);
					}
					if (vB[n] == "Q21")
					{
						vB[n] = buyPrice[buyPrice_f];
						buyPrice_f++;
					}
					else if (vB[n] == "Q22")
					{
						vB[n] = buyCount[buyCount_f];
						buyCount_f++;
					}
					else if (vB[n] == "Q23")
					{
						vB[n] = salePrice[salePrice_f];
						salePrice_f++;
					}
					else if (vB[n] == "Q24")
					{
						vB[n] = saleCount[saleCount_f];
						saleCount_f++;
					}
					else {
						map<string, string>::iterator it = datacollection.gtpFieldMap.find(vB[n]);
						if (it != datacollection.gtpFieldMap.end())
						{
							vB[n] = it->second;
						}
					}

					if (code == SELECT_REALTIME_QUOTATION_ANSWER)
					{
						if (datafields.find(vB[n]) != datafields.end())
						{
							datafields[vB[n]]->setValue(vB[n + 1]);
						}
					}
					else if (code == TRADE_REALTIME_QUOTATION_PUSH)
					{
						mapA.insert(pair<string, string>(vB[n], vB[n + 1]));
						if (vB[n] == "mardat")
							q012time += vB[n + 1];
						if (vB[n] == "martim")
							q012time += " " + vB[n + 1];
					}
				}

				if (code == SELECT_REALTIME_QUOTATION_ANSWER)
				{
					x03info.pgcontext->getPersistence()->save(x03info.pa);
				}
				else if (code == TRADE_REALTIME_QUOTATION_PUSH)
				{
					storeQ12Msg(context, mifps, module, mapA, subcode);
				}
			}
		}
		if (code == TRADE_REALTIME_QUOTATION_PUSH)
		{
			map<string, PageContext*>::iterator kmiit = datacollection.backTradePctx.find("kmipsh");
			if (kmiit != datacollection.backTradePctx.end())
			{
				kmiit->second->getTransaction()->service(string("KMISIM"), q012time);
			}
		}
	}
	catch (exception e)
	{
		logs(warning_, funcx + e.what()+messages);
	}
}


/**
 * 对进行了Q00字段买卖价转换的行情单条报文进行解析
 **/
string Simulation::storeQ12Msg(PageContext *context, ModuleList *mifps, Module *m, map<string, string> &simpleItemMap, string subcode)
{
	string key = TRADE_REALTIME_QUOTATION_PUSH;

	try {
		string cd = simpleItemMap.find("concod")->second;
		boost::mutex::scoped_lock lock0 = boost::mutex::scoped_lock(datacollection.QuotationMutex);  //行情List查找锁定
		Module* module = getContract(mifps, cd);	//从QuotationModule里找Module

		bool isNew = false;
		if (!module)
		{
			boost::mutex::scoped_lock lockmifps = boost::mutex::scoped_lock(mifps->getMutex());
			//TODO:对miflst加锁,需谨慎，防止死锁，之前没有对其加锁是因为不会修改miflst中的条目，因为一旦要修改就是重启的情况
			//从miflst中查找
			for (int i = 0; i < mifps->size(); i++)
			{
				Module* mm = mifps->get(i);
				Datafield* condf = mm->getDatafields()["concod"];
				if (ModuleUtils::getValue(condf) == cd)
				{
					module = mm;  //找到了该指针
					datacollection.QuotationModule.insert(pair<string, Module*>(cd, module));
					cout << "合约代码" << cd << "成功缓存" << endl;
					break;
				}
			}
			if (!module) {
				module = m->copy();
				mifps->_list.push_back(module);
				//TODO: add module to QuotationModule
				datacollection.QuotationModule.insert(pair<string, Module*>(cd, module));
				isNew = true;
			}

		}
		else
		{
			cout << "合约" << cd << "使用了缓存" << endl;
		}
		lock0.unlock();
		boost::mutex::scoped_lock lockA = boost::mutex::scoped_lock(module->getMutex());  //行情按行锁定
		map<string, Datafield*> datafields = module->getDatafields();
		map<string, string>::iterator it;

		//for debug temporary test
		//simpleItemMap.insert(pair<string, string>("instCode", "Au88.888"));
		for (it = simpleItemMap.begin(); it != simpleItemMap.end(); ++it)
		{
			string GTPkey = it->first;	//concod
			string value = it->second;	//Au99.99
			if (datafields.find(GTPkey) != datafields.end())
			{
				datafields[GTPkey]->setValue(value);
			}
		}
		if (isNew)
		{
			module->setAttribute("mop", "ADD");//全新添加
		}
		else  //只有非新，且mop为空才重新设置。假设mop为add，则需继续保持要求UI为ADD
		{
			string mop = module->getAttribute("mop");
			if (mop == "")
				module->setAttribute("mop", "UPDATE");
		}

		lockA.unlock();

		map<string, PageContext*>::iterator conit = datacollection.backTradePctx.find("condet");//抄送给condet，以刷新买卖价
		if (conit != datacollection.backTradePctx.end())
		{
			conit->second->getTransaction()->service(string(TRADE_REALTIME_QUOTATION_PUSH), cd);
		}

		return "";
	}
	catch (exception e)
	{
		logs(warning_, funcx + e.what());
		return "";
	}
}


/**
 * 解析非行情报文, 首先对报文中的数组类型展开得到一条或多条报文，在对单条报文字段进行对应值的赋值
 **/
void Simulation::parseOrdinaryPushMsg(PageContext *context, ModuleList *mifps, Module *md, string& data, string& code, string subcode)
{
	try {
		vector<string> vA;
		splitCombineMsg(data, vA);
		bool isReportCode = (code == ORDER_DEAL_PUSH || code == DELIVERY_ORDER_DEAL_PUSH || code == ORDER_PUSH || code == CANCEL_ORDER_PUSH || code == DELIVERY_ORDER_PUSH || code == CANCEL_DELIVERY_ORDER_PUSH || code == NEUTRALITY_ORDER_PUSH || code == CANCEL_NEUTRALITY_ORDER_PUSH);
		std::map<string, string> itemp_tot;
		map<string, Datafield*> dfmap = md->getDatafields();
		map<string, Datafield*>::iterator ittemp = dfmap.begin();
		for (; ittemp != dfmap.end(); ittemp++)  //制定map模板
		{
			itemp_tot[ittemp->first] = "";
		}

		for (int m = 0; m < vA.size(); ++m)
		{
			string s = vA[m];
			vector<string> vB;
			if (code == ISSUE_PROCLAIM_PUSH)
				vB.push_back(s);
			else
				Simulation::combinateMsgs(vB, s);
			for (int n = 0; n < vB.size(); ++n)
			{
				vector<string> vC;
				msgToVec(vC, vB[n]);
				size_t len = vC.size();
				map<string, string> mapA;
				for (size_t n = 0; n < len; n = n + 2)
				{
					replaceFormat_B(vC[n], vC[n + 1]);
					mapA.insert(pair<string, string>(vC[n], vC[n + 1]));
				}

				if (isReportCode)
				{
					parsePushBaodan(context, itemp_tot, mapA, code);
				}
				else
					parseRegPushMsgItem(context, mifps, md, mapA, code, subcode);
			}
		}
	}
	catch (exception e)
	{
		logs(warning_, funcx + e.what()+data);
	}
}

string replace_all(string str, const string old_value, const string new_value)
{
	for (string::size_type pos(0); pos != string::npos; pos += new_value.length()) {
		if ((pos = str.find(old_value, pos)) != string::npos)
			str.replace(pos, old_value.length(), new_value);
		else break;
	}
	return str;
}

void Simulation::parsePushBaodan(PageContext *context, map<string, string> tempMap_in, map<string, string> &simpleItemMap, string code)
{

	try
	{
		string prkey = simpleItemMap["O00"];	//	报单默认是报单编号
		if (code == ORDER_DEAL_PUSH || code == DELIVERY_ORDER_DEAL_PUSH)  //成交单以成交编号和买卖方向为唯一
		{
			prkey = simpleItemMap["O60"] + simpleItemMap["O02"];//主键带上买卖方向
		}

		if (simpleItemMap.find("T12") != simpleItemMap.end())
		{
			//申请时间+完整保单号
			if (prkey.size() == 8)prkey.insert(2, "0");
			std::string isnight = replace_all(simpleItemMap["T12"], ":", "");//合并所有排序字段，方便排序。
			long time = ModuleUtils::ston(isnight);
			if (time > 200000)
			{
				time = time - 200000;
			}
			else time = time + 40000;
			time = time * 100000000 + ModuleUtils::ston(prkey);
			simpleItemMap["isnight"] = itos(time);
		}
		else if (simpleItemMap.find("O62") != simpleItemMap.end())
		{
			//成交时间+成交编号
			std::string isnight = simpleItemMap["O62"] + simpleItemMap["O60"];  //合并所有排序字段，方便排序。
			if (simpleItemMap["O62"] > "20:00:00")
				simpleItemMap["isnight"] = "0" + isnight;
			else
				simpleItemMap["isnight"] = "1" + isnight;
		}

		if (code == ORDER_PUSH || code == CANCEL_ORDER_PUSH)
		{
			SBAODAN a;
			convertSBAODAN(&simpleItemMap, &a);
			insertOrUpdateData(INDEX_BAODAN, (void*)(&a));
		}
		else if (code == ORDER_DEAL_PUSH)
		{
			SCHENGJIAODAN a;
			convertSCHENGJIAODAN(&simpleItemMap, &a);

			insertOrUpdateData(INDEX_CHENGJIAODAN, (void*)(&a));
		}
		else if (code == DELIVERY_ORDER_PUSH || code == CANCEL_DELIVERY_ORDER_PUSH)
		{
			SJIAOGE a;
			convertSJIAOGE(&simpleItemMap, &a);
			insertOrUpdateData(INDEX_JIAOGE, (void*)(&a));

		}
		else if (code == NEUTRALITY_ORDER_PUSH || code == CANCEL_NEUTRALITY_ORDER_PUSH)
		{
			SZHONGLICANG a;
			convertSZHONGLICANG(&simpleItemMap, &a);
			insertOrUpdateData(INDEX_ZHONGLICANG, (void*)(&a));
		}
		else if (code == DELIVERY_ORDER_DEAL_PUSH)
		{
			SJG_ZLC_CHENGJIAODAN a;
			convertSJG_ZLC_CHENGJIAODAN(&simpleItemMap, &a);
			insertOrUpdateData(INDEX_JG_CHENGJIAODAN, (void*)(&a));
		}

	}
	catch (exception e)
	{
		logs(warning_, funcx + e.what() + code);
	}
}

/**
 * 对普通推送方式得到的单条报文进行解析
 **/
void Simulation::parseRegPushMsgItem(PageContext *context, ModuleList *mifps, Module *m, map<string, string> &simpleItemMap, string code, string subcode)
{

	//此处是为了支持其他不以合约代码为主键进行唯一验证的交易，例如报单是以订单号来判断的，成交单以成交编号+买卖::指定键在报文中的属性名
	string mprkey = m->getAttribute("mprkey");
	mprkey = mprkey == "" ? "I10" : mprkey;  //默认为I10
	//指定键在对象中的属性名
	string attr_prkey = m->getAttribute("prkey");
	attr_prkey = attr_prkey == "" ? "concod" : attr_prkey; //默认为concod 		
	string prkey = simpleItemMap[mprkey];	//	指定键的值

	long time1 = clock();
	stringstream ss;
	try
	{
		bool isFit = true;

		//完成收报筛选
		long time3 = clock();

		//判断module 是否包含这个主键，例如公告类就没有合约代码字段
		map<string, Datafield*> mapcc = m->getDatafields();
		Module *module = NULL;
		bool isNew = false;
		//成交回报不用判断主键
		if (mapcc.find(attr_prkey) != mapcc.end()) // 模型中包含主字段
		{
			boost::shared_lock<boost::shared_mutex> readLock(datacollection.delgteSharedMutex); //读锁
			module = getPushContract(mifps->getName(), prkey);	  //只允许同时只有一个线程去取到此module指针
			readLock.unlock();

			if (!module)
			{
				//特殊处理，B302
				if (code == DEFER_FEE_RATE_PAY_DIRECTION_PUSH || code == DELIVERY_REALTIME_QUOTATION_PUSH)
				{
					//再次查找下再列表里的行
					boost::mutex::scoped_lock lockB = boost::mutex::scoped_lock(mifps->getMutex());
					int size = mifps->size();
					for (int i = 0; i < size; i++)
					{
						Module * module_c = mifps->get(i);
						boost::mutex::scoped_lock lockOo = boost::mutex::scoped_lock(module_c->getMutex());
						string eprkey = ModuleUtils::getValue(module_c->getDatafields()["concod"]);
						if (eprkey == prkey)
						{
							module = module_c; //依旧保持锁
							boost::unique_lock<boost::shared_mutex> writeLock(datacollection.delgteSharedMutex);
							if (datacollection.delgteModule.find(mifps->getName() + prkey) == datacollection.delgteModule.end())
								datacollection.delgteModule.insert(make_pair(mifps->getName() + prkey, module));
							writeLock.unlock();
							//开始拷贝
							if (module->getAttribute("mop") == "")    //设置更新标记
							{
								module->setAttribute("mop", "UPDATE");
							}
							map<string, Datafield*> datafields = module->getDatafields();

							map<string, string>::iterator it;
							for (it = simpleItemMap.begin(); it != simpleItemMap.end(); ++it)
							{
								string GTPkey = it->first;
								map<string, string>::iterator ita = datacollection.gtpFieldMap.find(GTPkey);
								if (ita != datacollection.gtpFieldMap.end())
								{
									string key = datacollection.gtpFieldMap[GTPkey];
									string value = it->second;
									if (datafields.find(key) != datafields.end())
									{

										datafields[key]->setValue(value);
									}
								}
								else {
									string value = it->second;
									if (datafields.find(GTPkey) != datafields.end())
									{
										datafields[GTPkey]->setValue(value);
									}
								}
							}
							return;
						}
					}
					lockB.unlock();
				}
				if (!module)  //再次判断，避免B302 Q202判断出问题
				{
					boost::unique_lock<boost::shared_mutex> writeLock(datacollection.delgteSharedMutex);
					map<string, Module*>::iterator it = datacollection.delgteModule.find(mifps->getName() + prkey);
					if (it == datacollection.delgteModule.end())
					{
						module = m->copy();
						module->setAttribute("mop", "ADD");
						isNew = true;
						module->getMutex().lock();  //立即锁定,防止被其他线程抢用
						datacollection.delgteModule[mifps->getName() + prkey] = module; //如有主键，建立缓存
					}
					else
						module = it->second;
				}
			}
		}
		else
		{
			//没有主键的情况，直接加入 如公告报文
			module = m->copy();
			isNew = true;
			module->setAttribute("mop", "ADD");
			module->getMutex().lock();  //立即锁定,防止被其他线程抢用
		}
		//TODO:mifps锁的粒度需要加大？？
		boost::mutex::scoped_lock lockB = boost::mutex::scoped_lock(mifps->getMutex());

		if (isNew)
		{
			//NOTE:如果界面出现某条合约展示2条信息，其中一条只有合约代码和默认值，另一个没有合约代码只有收获量等信息
			//原因可能是此处对mifps两次上锁之间，收到了该合约的合约信息，在cotp处，进行了add，此处也进行add
			
			//TODO:visit list check concod is exist?
			//先赋值
			long timeNA = clock();

			map<string, Datafield*> datafields = module->getDatafields();

			map<string, string>::iterator it;
			for (it = simpleItemMap.begin(); it != simpleItemMap.end(); ++it)
			{
				string GTPkey = it->first;
				map<string, string>::iterator ita = datacollection.gtpFieldMap.find(GTPkey);
				if (ita != datacollection.gtpFieldMap.end())
				{
					string key = datacollection.gtpFieldMap[GTPkey];
					string value = it->second;
					if (datafields.find(key) != datafields.end())
					{

						datafields[key]->setValue(value);
					}
				}
				else {
					string value = it->second;
					if (datafields.find(GTPkey) != datafields.end())
					{
						datafields[GTPkey]->setValue(value);
					}
				}
			}
			//公告
			if (code == ISSUE_PROCLAIM_PUSH)  //插入行  公告末尾插入
			{
				vector<Module*>::iterator jgcit = mifps->_list.begin();
				for (; jgcit != mifps->_list.end(); jgcit++)
				{
					string pubind = (*jgcit)->getDatafields()["pubind"]->getValue();
					string t80 = simpleItemMap["T80"];
					if (pubind < t80)
						break;
				}
				mifps->_list.insert(jgcit, module);
				if (simpleItemMap["X04"] == "2") // 席位流公告
				{
					SGONGGAO a;
					convertSGONGGAO(&simpleItemMap, &a);
					insertOrUpdateData(INDEX_GONGGAO, (void*)(&a));
				}
			}
			else
			{
				mifps->_list.push_back(module);//把此行代码挪到copy module处？no!设置mop为新增，然后更新数据，如果mop为""则将mop改为update？？？
				//目前的做法存在对mifps加锁的空隙，处理收到合约的情况，此时处理合约的逻辑会新增一个合约，此处也新增合约，导致某一合约出现2次
			}

			module->setParent(mifps);
			module->getMutex().unlock();

			lockB.unlock();
			return; //新增处理完毕
		}
		//开始复制
		//旧Module开始复制
		long timeF = clock();
		int size1 = mifps->size();
		bool dobCheck = false;
		for (int i = 0; i < size1; i++)
		{
			if (module == mifps->get(i))
				dobCheck = true;
		}
		if (!dobCheck)
			return;
		boost::mutex::scoped_lock lockO = boost::mutex::scoped_lock(module->getMutex());
		map<string, Datafield*> datafields = module->getDatafields();
		map<string, Datafield*>::iterator itOb = datafields.find("X05");
		map<string, string>::iterator itOs = simpleItemMap.find("X05");
		bool flag = false;
		if (itOb != datafields.end() && itOs != simpleItemMap.end())
		{
			//都找到了报单状态，则判断是否应该覆盖
			string o09_new = itOs->second;  //新单
			string o09_old = ModuleUtils::getValue(itOb->second); //旧单

			if (ModuleUtils::ston(o09_new) > ModuleUtils::ston(o09_old)) flag = true;
		}
		else
			flag = true;//必须设置为true，释放其他类型报文的刷新
		if (!flag)
			return;

		if (module->getAttribute("mop") == "")    //设置更新标记
		{
			module->setAttribute("mop", "UPDATE");
		}
		//map<string, Datafield*> datafields = module -> getDatafields();
		ModuleUtils::clear(module);	//撤单了就清理掉原来的模型
		map<string, string>::iterator it;
		for (it = simpleItemMap.begin(); it != simpleItemMap.end(); ++it)
		{
			string GTPkey = it->first;
			map<string, string>::iterator ita = datacollection.gtpFieldMap.find(GTPkey);
			if (ita != datacollection.gtpFieldMap.end())
			{
				string key = datacollection.gtpFieldMap[GTPkey];
				string value = it->second;
				if (datafields.find(key) != datafields.end())
				{

					datafields[key]->setValue(value);
				}
			}
			else {
				string value = it->second;
				if (datafields.find(GTPkey) != datafields.end())
				{
					datafields[GTPkey]->setValue(value);
				}
			}
		}
	}
	catch (exception e)
	{
		logs(warning_, funcx + e.what()+code);
	}
}


void Simulation::request(PageContext *context, ReadSetAble *mifps, Module *module, PersistenceAble *pa, string& tradeMsg, string& x07)
{
	try {
		boost::mutex::scoped_lock lockT(datacollection.tradeMutex);
		x07 = "";
		size_t x07index = tradeMsg.find("X07");

		if (x07index == tradeMsg.npos)
		{
			x07 = ModuleUtils::getLocalCodeRandomNum(8);
			tradeMsg += ",X07=" + x07;
		}
		else
		{
			size_t equalSignIndex = tradeMsg.find("=", x07index);
			size_t dotIndex = tradeMsg.find(",", x07index);
			x07 = tradeMsg.substr(equalSignIndex + 1, dotIndex - equalSignIndex - 1);
		}
		context->getPersistence()->setSql(&DbOperation::GlobalSql);
		if (mifps != NULL)
		{
			string qryCondition = "";
			if (x07 == "")
			{
				context->getPersistence()->readSet(mifps, qryCondition);
			}
			return;
		}
		string auditkey;
		LockUnit *lock = datacollection.lockmng.generateLock();
		auditkey = x07;
		x03Infos info = { context, mifps, module, pa, lock, pa->dbTableName };
		if (datacollection.tradeMesgInfo.find(datacollection.globalUsername) == datacollection.tradeMesgInfo.end())
		{
			map<string, x03Infos> x03m;
			x03m.insert(pair<string, x03Infos>(x07, info));
			datacollection.tradeMesgInfo.insert(pair<string, map<string, x03Infos>>(datacollection.globalUsername, x03m));
		}
		else
		{
			datacollection.tradeMesgInfo.find(datacollection.globalUsername)->second[x07] = info;
		}
		lockT.unlock();
		//TODO
		//发送请求报文
		SgeNet::instance()->send_msg(tradeMsg);

		string x03 = getFieldValue(tradeMsg, "X03");
		//string x03pair = datacollection.requestAnswerMap[x03];
		Audit::instance()->getAuditJson(tradeMsg);
		int time = ModuleUtils::ston(datacollection.configMap.find("timeout")->second);
		if (time > 60 || time < 3)time = 10;

		lock->lockB = boost::mutex::scoped_lock(lock->mt, boost::chrono::milliseconds(time * 1000));
		boost::mutex::scoped_lock lockT2(datacollection.tradeMutex);//避免全局map操作出问题
		long timeX1 = clock();
		logs(debug_, x07 + "tradeMutex锁获取" + itos(timeX1));

		if (lock->lockB)
		{
			this->returnCode = lock->returnValue;
		}
		else {
			map < string, string >::iterator iter;
			iter = datacollection.TimeOoutMap.find(x03);
			string tips_str = "未知操作类型";
			if (iter != datacollection.TimeOoutMap.end()) {
				tips_str = iter->second;
			}
			this->returnCode = "RSP999999#" + tips_str + "超时!";
		}
		datacollection.lockmng.removeLock(lock->id);
		datacollection.tradeMesgInfo.find(datacollection.globalUsername)->second.erase(x07);
		lockT2.unlock();
		long timeX2 = clock();
		logs(debug_, x07 + "tradeMutex锁释放" + itos(timeX2));

		boost::mutex::scoped_lock lockM(module->getMutex()); //避免临界冲突
		long timeX = clock();
		logs(debug_, x07 + "锁释放" + itos(timeX));
	}
	catch (exception e)
	{
		logs(warning_, funcx + e.what());
	}
}

/**
 * 模拟发送请求报文并等待响应报文后处理 请求应答报文
 **/
void Simulation::request(PageContext *context, ReadSetAble *mifps, Module *module, PersistenceAble *pa, string& tradeMsg)
{
	try {
		boost::mutex::scoped_lock lockT(datacollection.tradeMutex);
		string x07 = "";
		size_t x07index = tradeMsg.find("X07");

		if (x07index == tradeMsg.npos)
		{
			x07 = ModuleUtils::getLocalCodeRandomNum(8);
			tradeMsg += ",X07=" + x07;
		}
		else
		{
			size_t equalSignIndex = tradeMsg.find("=", x07index);
			size_t dotIndex = tradeMsg.find(",", x07index);
			x07 = tradeMsg.substr(equalSignIndex + 1, dotIndex - equalSignIndex - 1);
		}
		context->getPersistence()->setSql(&DbOperation::GlobalSql);
		if (mifps != NULL)
		{
			string qryCondition = "";
			if (x07 == "")
			{
				context->getPersistence()->readSet(mifps, qryCondition);
				return;
			}

		}
		string auditkey;
		LockUnit *lock = datacollection.lockmng.generateLock();
		auditkey = x07;
		x03Infos info = { context, mifps, module, pa, lock, pa->dbTableName };
		if (datacollection.tradeMesgInfo.find(datacollection.globalUsername) == datacollection.tradeMesgInfo.end())
		{
			map<string, x03Infos> x03m;
			x03m.insert(pair<string, x03Infos>(x07, info));
			datacollection.tradeMesgInfo.insert(pair<string, map<string, x03Infos>>(datacollection.globalUsername, x03m));
		}
		else
		{
			datacollection.tradeMesgInfo.find(datacollection.globalUsername)->second[x07] = info;
		}
		lockT.unlock();
		//TODO
		//发送请求报文
		SgeNet::instance()->send_msg(tradeMsg);

		string x03 = getFieldValue(tradeMsg, "X03");
		//string x03pair = datacollection.requestAnswerMap[x03];
		Audit::instance()->getAuditJson(tradeMsg);
		lock->lockB = boost::mutex::scoped_lock(lock->mt, boost::chrono::milliseconds(10000));

		long timeX1 = clock();
		logs(debug_, x07 + "tradeMutex锁获取" + itos(timeX1));

		if (lock->lockB)
		{
			this->returnCode = lock->returnValue;
			if (lock->dblmt.active_count == 0)
			{
				if (mifps)
				{
					ModuleList* mlist = dynamic_cast<ModuleList*>(mifps);
					if (mlist)
						mlist->getTransaction()->_pageCtx->getPresentation()->setModified(mlist); //补充一句setModify
				}
			}
			else
				lock->dblmt.lock();
		}
		else {
			map < string, string >::iterator iter;
			iter = datacollection.TimeOoutMap.find(x03);
			string tips_str = "未知操作类型";
			if (iter != datacollection.TimeOoutMap.end()) {
				tips_str = iter->second;
			}
			this->returnCode = "RSP999999#" + tips_str + "超时!";
			if (mifps)
			{
				ModuleList* mlist = dynamic_cast<ModuleList*>(mifps);
				if (mlist)
					mlist->getTransaction()->_pageCtx->getPresentation()->setModified(mlist); //补充一句setModify
			}
		}
		boost::mutex::scoped_lock lockT2(datacollection.tradeMutex);//避免全局map操作出问题
		datacollection.lockmng.removeLock(lock->id);
		datacollection.tradeMesgInfo.find(datacollection.globalUsername)->second.erase(x07);
		lockT2.unlock();
		long timeX2 = clock();
		logs(debug_, x07 + "tradeMutex锁释放" + itos(timeX2));

		boost::mutex::scoped_lock lockM(module->getMutex()); //避免临界冲突
		long timeX = clock();
		logs(debug_, x07 + "锁释放" + itos(timeX));
	}
	catch (exception e)
	{
		logs(warning_, funcx + e.what());
	}
}

/**
 * 对待行情报文，根据行情类别查找行情列表中对应的行情数据项，并返回该数据项
 **/
Module * Simulation::getContract(ModuleList *mifps, string code)
{
	try {
		map<string, Module*> qm = datacollection.QuotationModule;
		map<string, Module*>::iterator it = qm.find(code);
		if (it != qm.end())
		{
			return it->second;
		}
		return NULL;
	}
	catch (exception e)
	{
		logs(warning_, funcx + e.what());
		return NULL;
	}
}

/**
 * 对根据主键需要update的报文，避免每次耗费效率,从Map缓存中获取
 **/
Module * Simulation::getPushContract(string tablename, string keyval)
{
	try {
		map<string, Module*> qm = datacollection.delgteModule;
		map<string, Module*>::iterator it = qm.find(tablename + keyval);
		if (it != qm.end())
		{
			return it->second;
		}
		return NULL;
	}
	catch (exception e)
	{
		logs(warning_, funcx + e.what());
		return NULL;
	}
}


/**
 *  获取GTP字符串中的消息报文
 **/
string Simulation::getMsgBody(string str)
{
	//循环删除报文信息中报文头各个字段以及报文长度信息
	string ary[10] = { "X01","X02","X03","X04","X05","X06","X07","X08","X09" };
	for (int i = 0; i < 10; ++i)
	{
		string substr = ary[i];
		size_t index = str.find(substr);
		if (index != str.npos)
		{
			size_t m = str.find(",", index);
			if (m != str.npos)
			{
				str = str.erase(index, m - index + 1);
			}
			else {
				str = str.erase(index);
			}
		}
	}
	if (str.rfind(",") == str.size() - 1)
	{
		str = str.erase(str.size() - 1, 1);
	}
	return str;
}

/**
 * 获取GTP字段域中各键值对，并存储到map中
 **/
void Simulation::getGTPMap(map<string, string> &gtpDataMap, string& gtpString)
{
	size_t front = 0;
	size_t rear = gtpString.find(",");
	while (rear != gtpString.npos)
	{
		string str = gtpString.substr(front, rear - front);
		size_t i = str.find("=");
		string key = str.substr(0, i);
		string value = str.substr(i + 1);
		gtpDataMap.insert(pair<string, string>(key, value));
		front = rear + 1;
		rear = gtpString.find(",", front);
		if (rear == gtpString.npos)
		{
			str = gtpString.substr(front, gtpString.size() - front);
			if (str == "")continue;
			size_t i = str.find("=");
			string key = str.substr(0, i);
			string value = str.substr(i + 1);
			gtpDataMap.insert(pair<string, string>(key, value));
		}

	}
}


string Simulation::getNoAryMsg(string& msg)
{
	size_t start = msg.find("[");
	if (start != msg.npos)
	{
		start = start - 5;
		size_t end = msg.rfind("]");
		string s = msg.erase(start, end - start + 1);
		return s;
	}
	else {
		return msg;
	}
}

//将组合在一起的分包数据进行拆分
void Simulation::splitCombineMsg(string &msg, vector<string> &v)
{
	size_t start = 0;
	size_t end = msg.find("_###_", start);
	while (end != msg.npos)
	{
		string s = msg.substr(start, end - start);
		v.push_back(s);
		start = end + 5;
		end = msg.find("_###_", start);
	}
	if (end == msg.npos)
	{
		string s = msg.substr(start);
		v.push_back(s);
	}
}

/**
 * 将带分组的报文拆分成多个单独报文
 **/
void Simulation::combinateMsgs(vector<string> &msgsVector, string& item, string upLevelMsg)
{
	try {
		int isq911 = 0;
		if (item.find("X03=Q911") != item.npos)
		{
			isq911 = 2;
		}

		if (item.find("[") != item.npos)
		{
			string basePart;
			string arrayPart;
			size_t i = item.find("[");
			size_t j = item.rfind("]");
			size_t m = item.rfind(",", i);
			arrayPart = item.substr(i + 1, j - i - 1);
			basePart = item.erase(m, j - m + 1);
			vector<string> aryItems;

			size_t f = arrayPart.find("}]");
			if (f != arrayPart.npos)
			{
				size_t dotIndex = arrayPart.find("}", f + 1);
				while (dotIndex != arrayPart.npos)
				{
					string aryItem = arrayPart.substr(0, dotIndex + 1);
					aryItem = aryItem.erase(0, 1);
					aryItem = aryItem.erase(aryItem.size() - 1, 1);
					aryItems.push_back(aryItem);
					if (dotIndex != arrayPart.size() - 1)
					{
						arrayPart = arrayPart.erase(0, dotIndex + 2);
					}
					else {
						arrayPart = "";
					}
					f = arrayPart.find("}]");
					if (f == arrayPart.npos)
					{
						break;
					}
					size_t dotIndex = arrayPart.find("}", f + 1);
				}
			}
			else if (arrayPart.find("Q82") != arrayPart.npos)
			{
				arrayPart.replace(arrayPart.rfind("}"), 1, "},");
				for (size_t i = 0; i < arrayPart.size(); i++)
				{
					if (arrayPart.find("},Q85") != arrayPart.npos)
					{
						arrayPart.replace(arrayPart.find("},Q85"), 5, "} ,Q85");
					}
					else if (arrayPart.find("},G20") != arrayPart.npos)
					{
						arrayPart.replace(arrayPart.find("},G20"), 5, "} ,G20");
					}
				}
				size_t dotIndex = arrayPart.find("},");
				while (dotIndex != arrayPart.npos)
				{
					string aryItem = arrayPart.substr(0, dotIndex + 1);
					aryItem = aryItem.erase(0, 1);
					aryItem = aryItem.erase(aryItem.size() - 1, 1);

					aryItems.push_back(aryItem);
					if (dotIndex != arrayPart.size() - 1)
					{
						arrayPart = arrayPart.erase(0, dotIndex + 2);
					}
					else {
						arrayPart = "";
					}
					dotIndex = arrayPart.find("},");
				}
			}
			else {
				arrayPart.replace(arrayPart.rfind("}"), 1, "},");
				size_t dotIndex = arrayPart.find("},");
				while (dotIndex != arrayPart.npos)
				{
					string aryItem = arrayPart.substr(0, dotIndex + 1);
					aryItem = aryItem.erase(0, 1);
					aryItem = aryItem.erase(aryItem.size() - 1, 1);
					aryItems.push_back(aryItem);
					if (dotIndex != arrayPart.size() - 1)
					{
						arrayPart = arrayPart.erase(0, dotIndex + 2);
					}
					else {
						arrayPart = "";
					}
					dotIndex = arrayPart.find("},");
				}
			}

			vector<string>::iterator it;
			for (it = aryItems.begin(); it != aryItems.end(); ++it)
			{
				if (isq911 == 2)
				{
					string r = basePart + "," + *it;//upLevelMsg + "," + item;
					msgsVector.push_back(r);
				}
				else {
					string s = (upLevelMsg == "") ? basePart : (upLevelMsg + "," + basePart);
					Simulation::combinateMsgs(msgsVector, *it, s);
				}
			}isq911 = 0;
		}
		else {
			string r = (upLevelMsg == "") ? item : (upLevelMsg + "," + item);//upLevelMsg + "," + item;
			msgsVector.push_back(r);
		}
	}
	catch (exception e)
	{
		logs(warning_, funcx + e.what());
	}
}

//将报文分割为键和值组成的vecor，以便对字段名进行替换
void Simulation::msgToVec(vector<string> &vt, string &gtpString)
{
	size_t front = 0;
	size_t rear = gtpString.find(",");
	while (rear != gtpString.npos)
	{
		if (gtpString.at(rear - 1) == '\\')
		{
			size_t nrear = rear - 2;
			int rearcnt = 0;
			while (nrear >= 0 && gtpString.at(nrear) == '\\')
			{
				rearcnt++;
				nrear--;
			}
			if (rearcnt % 2 == 0)
			{
				if (rear + 1 < gtpString.size())
				{
					rear = gtpString.find(",", rear + 1);  //对转义逗号做处理
					continue;
				}
				else
					break;
			}
		}
		string str = gtpString.substr(front, rear - front);
		size_t i = str.find("="); //域号后面必定是等于号，所以可以不用判断是否转义
		string key = str.substr(0, i);
		string value = str.substr(i + 1);
		if (value.find("\\") != value.npos)
		{
			char* buf = new char[value.size()];
			memset(buf, 0, value.size());
			int n = 0;
			for (size_t m = 0; m < value.size(); m++)
			{
				if (value.at(m) == '\\' && m + 1 < value.size())
				{
					char c = value.at(m + 1);
					switch (c)
					{
					case '\\':
					case '[':
					case ']':
					case '{':
					case '}':
					case ',':
					case '=':buf[n] = value.at(m + 1); m++; break;
					default:
						buf[n] = value.at(m);
					}
					n++;
				}
				else
				{
					buf[n] = value.at(m);
					n++;
				}
			}
			value = string(buf);
			delete buf;
		}
		vt.push_back(key);
		if (key == "Q84" || key == "Q85")
			value += " ";
		vt.push_back(value);
		front = rear + 1;
		//末尾判断
		rear = gtpString.find(",", front);
	}
	//处理最后一个域号
	if (front < gtpString.size())
	{
		string str = gtpString.substr(front, gtpString.size() - front);
		if (str == "") return;
		size_t i = str.find("=");
		string key = str.substr(0, i);
		string value = str.substr(i + 1);
		if (key == "Q84" || key == "Q85")
			value = " " + value + " ";
		vt.push_back(key);
		vt.push_back(value);
	}
}


//使用报文解析值设置指定对象中各值
void Simulation::setValues(map<string, string> &kvMap, map<string, Datafield*> &datafields)
{
	map<string, string>::iterator it;
	for (it = kvMap.begin(); it != kvMap.end(); ++it)
	{
		string key = it->first;
		string value = it->second;
		if (datafields.find(key) != datafields.end())
		{
			datafields[key]->setValue(value);
		}
	}
}

//处理数据的补零方法
string buling(int num)
{
	string temp = "";
	for (int i = 0; i < num; i++)
	{
		temp += "0";
	}
	return temp;
}

//替换推送报文单位格式
void Simulation::replaceFormat(string &key, string &value)
{
	if (key != "Q25")
	{
		map<string, formatStruct>::iterator it = datacollection.formatMap.find(key);
		if (it != datacollection.formatMap.end())
		{
			bool fushu = false;
			if (value.find("-") != value.npos)
			{
				fushu = true;
				value = value.substr(1);
			}
			size_t jd = itos(it->second.divisionDigit).size() - 1;//精度
			size_t xs = it->second.precision;//小数点
			int flag = 0;
			string temp1 = "", temp2 = "";
			if (value.find(".") != value.npos)
			{
				flag = 1;
				temp1 = value.substr(0, value.find("."));
				temp2 = value.substr(value.find(".") + 1);
			}
			else temp1 = value;
			if (temp1.size() > jd)
			{
				temp1.insert(temp1.size() - jd, ".", 1);
			}
			else
			{
				string temp = "0.";
				temp += buling(jd - temp1.size());
				temp1 = temp + temp1;
			}
			if (temp2.size() >= xs)
			{
				temp2 = temp2.substr(0, xs);
			}
			else temp2 += buling(xs - temp2.size());
			value = temp1 + temp2;

			if (jd >= xs)
			{
				value = value.substr(0, value.find(".") + xs + 1);
			}

			if (fushu)
			{
				value = "-" + value;
			}
		}
	}
}


//替换应答报文单位格式A
void Simulation::replaceFormat_A(string &key, string &value)
{
	stringstream ssm;
	map<string, formatStruct>::iterator it = datacollection.formatMap.find(key);
	if (it != datacollection.formatMap.end())
	{
		int div = (int)log10((double)it->second.divisionDigit);
		int inspos = (int)value.length() - div;
		string s;
		if (inspos > 0)
		{
			s = value.insert(inspos, ".");
		}
		else if (inspos < 0)
		{
			ssm << abs(inspos);
			string fmt = "%0" + ssm.str() + "d";
			char buf[10];
			sprintf(buf, fmt.c_str(), 0);
			s = "0." + string(buf) + value;
			ssm.clear();
		}
		else
		{
			s = "0." + value;
		}
		size_t n = s.find(".");
		if (s.length() - 1 - n > it->second.precision)
		{
			size_t c = n + it->second.precision + 1;
			s = s.erase(c);
		}
		else if (s.length() - 1 - n < it->second.precision)
		{
			size_t u = it->second.precision - s.length() + 1 + n;
			while (u != 0)
			{
				s = s + "0";
				u--;
			}
		}
		value = s + it->second.unit;
	}
}

//替换应答报文单位格式B
void Simulation::replaceFormat_B(string &key, string &value)
{
	map<string, formatStruct>::iterator it = datacollection.formatMap.find(key);
	if (it != datacollection.formatMap.end())
	{
		bool fushu = false;
		if (value.find("-") != value.npos)
		{
			fushu = true;
			value = value.substr(1);
		}
		size_t jd = itos(it->second.divisionDigit).size() - 1;//精度
		size_t xs = it->second.precision;//小数点
		int flag = 0;
		string temp1 = "", temp2 = "";
		if (value.find(".") != value.npos)
		{
			flag = 1;
			temp1 = value.substr(0, value.find("."));
			temp2 = value.substr(value.find(".") + 1);
		}
		else temp1 = value;
		if (temp1.size() > jd)
		{
			temp1.insert(temp1.size() - jd, ".", 1);
		}
		else
		{
			string temp = "0.";
			temp += buling(jd - temp1.size());
			temp1 = temp + temp1;
		}
		if (temp2.size() >= xs)
		{
			temp2 = temp2.substr(0, xs);
		}
		else temp2 += buling(xs - temp2.size());
		value = temp1 + temp2;

		if (jd >= xs)
		{
			value = value.substr(0, value.find(".") + xs + 1);
		}

		if (fushu)
		{
			value = "-" + value;
		}
	}
}

//解析T092和T122类型的报文是
string Simulation::T092_T122(string& msg)
{
	size_t start = msg.find("S95");
	if (start == msg.npos)
	{
		return msg;
	}
	string partA = msg.erase(start, 6);
	size_t end = partA.find("]");
	partA = partA.erase(end - 1, 2);
	size_t n = partA.find("{");
	if (n != partA.npos)
	{
		partA = partA.erase(n, 1);
	}
	n = partA.find("}");
	if (n != partA.npos)
	{
		partA = partA.erase(n, 1);
	}
	n = partA.find("V00");
	if (n != partA.npos)
	{
		partA = partA.replace(n, 3, "varcod");
	}
	n = partA.find("T52");
	if (n != partA.npos)
	{
		partA = partA.replace(n, 3, "stdwei");
	}
	n = partA.find("V00");
	if (n != partA.npos)
	{
		partA = partA.replace(n, 3, "varcod2");
	}
	n = partA.find("T52");
	if (n != partA.npos)
	{
		partA = partA.replace(n, 3, "stdwei2");
	}
	return partA;
}

void Simulation::pushBaseData(const string& msg, const string& uri) {
	map<string, sessionInfo*>::iterator it = datacollection.sessionInfoMap.find(datacollection.globalUsername);
	if (it != datacollection.sessionInfoMap.end())
	{
		if (!it->second || !it->second->session) {
			logs(warning_, "Simulation::pushBaseData session is null");
			return;
		}

		Session* session = it->second->session;
		if (!session->getContext() || !session->getContext()->getUiSupport()) {
			logs(error_, "Simulation::pushBaseData context or uiuupport is null");
			return;
		}
		InfoSwitch* infoSwitch = dynamic_cast<InfoSwitch*>(session->getContext()->getUiSupport());
		string json = DataParse::singleGtp2json((string &)msg);
		eComponet ec;
		ec.action = "BaseData";
		ec.uri = uri;
		ec.value = json;
		infoSwitch->push(ec);
	}
	else {
		logs(error_, "Simulation::pushBaseData, find session failed");
	}
}

bool Simulation::getInstDataFromInstMsgPush(const string& msg, string& instId, string& instCode) {
	auto gtphash = shared_ptr<GtpHash>(GtpHash::createGtpHash((string &)msg));
	string cmd = gtphash->getFieldValueS("X03");
	if (cmd != INST_MESSAGE_PUSH) {
		logs(error_, __FUNCTION__" wrong caller! msg = " + msg);
		return false;
	}
	instId = gtphash->getFieldValueS(INST_ID_FIELD);
	if (instId == "")
	{
		logs(error_, __FUNCTION__" 处理合约信息回报出错，获取到的InstId为空，msg=" + msg);
		return false;
	}
	instCode = gtphash->getFieldValueS(INST_CODE_FIELD);
	if (instCode == "")
	{
		logs(error_, __FUNCTION__" 处理合约信息回报出错，获取到的InstCode为空，msg=" + msg);
		return false;
	}
	return true;
}

bool Simulation::addInstCode2DF(string& instId, map<string, Datafield*>& datafields)
{
	if (instId == "")
	{
		logs(error_, "addInstCode2DF 出错，instId为空");
		datafields["instCode"]->setValue("");
		return false;
	}
	string instCode = InstDataConverter::InstId2Code(instId.c_str());
	if (instCode == "")
	{
		logs(warning_, "addInstCode2DF 出错，调用InstDataConverter::InstId2Code 失败，返回值为空");
		datafields["instCode"]->setValue("");
		return false;
	}
	datafields["instCode"]->setValue(instCode);
	return true;
}

bool Simulation::addInstCode2DataFields(map<string, Datafield*>& datafields)
{
	//get instid
	string instid = datafields["concod"]->getValue();	//前提要保证有concod

	return addInstCode2DF(instid, datafields);
}

bool Simulation::addInstCode2Match(map<string, string>& matchMap)
{
	return addInstCode2Record(matchMap);
}

bool Simulation::addInstCode2Record(map<string, string>& recordMap)
{
	map<string, string> ::iterator it = recordMap.find("concod");
	if (it != recordMap.end())
	{
		if (addInstCode2Map(it->second, recordMap) == false)
		{
			logs(warning_, "addInstCode2Record 调用 addInstCode2Map失败，返回false.");
			return false;
		}
		return true;
	}
	else
	{
		logs(error_, "addInstCode2Record出错，查找concod返回recordMap.end()");
		return false;
	}
}

bool Simulation::addInstCode2Map(string& instId, map<string, string>& dataMap)
{
	if (instId == "")
	{
		logs(error_, "addInstCode2Map 失败，instId为空");
		dataMap.insert(pair<string, string>("instCode", ""));
		return false;
	}
	string instCode = InstDataConverter::InstId2Code(instId.c_str());
	if (instCode == "")
	{
		logs(warning_, "addInstCode2Map 调用InstDataConverter::InstId2Code 失败，返回值为空");
		dataMap.insert(pair<string, string>("instCode", ""));
		return false;
	}
	//auto ret = dataMap.insert(pair<string, string>("instCode", instCode));
	//return ret.second;
	dataMap["instCode"] = instCode;
	return true;
}